package sxe.core.math;

import snobject.snDouble;
import snobject.snInteger;
import snobject.snObject;
import snobject.snObjectArgList;
import step.EvaluationFailure;
import step.FunctionWrapper;

/**
 * Returns the greatest value.
 * That is, the result is the argument closer to positive infinity.
 * If the arguments have the same value, the result is that same value.
 * @param argv must contain snInteger or snDouble objects in the stack
 * @return returns the largest of a set of values
 */

public class max extends FunctionWrapper{
	
	public snObject Call(snObjectArgList argv) throws EvaluationFailure{
		// REQUIRES: argv must contain snInteger or snDouble objects in the stack
		// EFFECTS: returns the snObject of the largest of a set of values
		boolean isDbl = false;
		double ret = 0, x = 0;
		int index = argv.index();
		
		if(argv.popObject() instanceof snDouble){
			ret = ((snDouble)argv.objectAt(index)).getDouble();
			isDbl = true;
		}
		else
			ret = ((snInteger)argv.objectAt(index)).getInteger();
		
		while(argv.hasNext()){
			index++;
			if(argv.popObject() instanceof snDouble){
				x = ((snDouble)argv.objectAt(index)).getDouble();
				if(ret < x){
					ret = x;
					isDbl = true;
				}
			}
			else{
				x = ((snInteger)argv.objectAt(index)).getInteger();
				if(ret < x){
					ret = x;
					isDbl = false;
				}
			}
		}
		
		if(isDbl)
			return new snDouble(new Double(ret));
		else
			return new snInteger(new Integer((new Double (ret)).intValue()));
	}
}